﻿namespace System;
/// <inheritdoc/>
public abstract class Specification<T> : ISpecification<T>
{
    #region Public Methods
    /// <inheritdoc/>
    public static Specification<T> Eval(Expression<Func<T, bool>> expression) => new ExpressionSpecification<T>(expression);
    #endregion
    #region ISpecification<T> Members
    /// <inheritdoc/>
    public virtual bool IsSatisfiedBy(T obj) => this.GetExpression().Compile()(obj);
    /// <inheritdoc/>
    public ISpecification<T> And(ISpecification<T> other) => new AndSpecification<T>(this, other);
    /// <inheritdoc/>
    public ISpecification<T> Or(ISpecification<T> other) => new OrSpecification<T>(this, other);
    /// <inheritdoc/>
    public ISpecification<T> AndNot(ISpecification<T> other) => new AndNotSpecification<T>(this, other);
    /// <inheritdoc/>
    public ISpecification<T> Not() => new NotSpecification<T>(this);
    /// <inheritdoc/>
    public abstract Expression<Func<T, bool>> GetExpression();
    #endregion
}
